package org.mtmi.io.controls;

import java.io.IOException;

import net.n3.nanoxml.IXMLElement;

import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.mtmi.io.IControlIO;
import org.mtmi.io.ReaderError;
import org.mtmi.io.SceneReader;
import org.mtmi.io.SceneWriter;
import org.mtmi.io.XMLReader;
import org.mtmi.io.XMLWriter;
import org.mtmi.ui.controls.Control;
import org.mtmi.ui.controls.IOrientable;

/**
 * Basic feature of a {@link Control}:
 * <ul>
 * <li> control's bounds.
 * <li> control's orientation if control is an instanceof {@link IOrientable} 
 * </ul>
 * <br>
 * Feature subclasses can enabled:
 * <ul>
 * <li>Background color
 * <li>Foreground color
 * <ul>
 * By default all feature are saved, some of them cannot be saved using {@link #setProcessFeature(int, boolean)}
 */
public class ControlIO implements IControlIO
{
	public static final int F_BOUNDS=0;
	public static final int F_ORIENTATION=1;
	public static final int F_BACKGROUND_COLOR=2;
	public static final int F_FOREGROUND_COLOR=3;
	//let me last please
	private static final int LAST=4;
	
	private boolean process[];
	
	public ControlIO()
	{
		process = new boolean[ LAST ];
		//feature processed by default:
		process[ F_BOUNDS ] = true;
		process[ F_ORIENTATION ] = true;
		//other feature may be enabled by subclasses
	}
	
	public void setProcessFeature( int feature, boolean save_feature ) {
		process[ feature ] = save_feature;
	}
	
	public static final String E_BOUNDS="bounds"; //$NON-NLS-1$
	public static final String A_X ="x"; //$NON-NLS-1$
	public static final String A_Y ="y"; //$NON-NLS-1$
	public static final String A_W ="w"; //$NON-NLS-1$
	public static final String A_H ="h"; //$NON-NLS-1$
	
	public static final String E_COLORS="colors"; //$NON-NLS-1$
	public static final String A_BG="bg"; //$NON-NLS-1$
	public static final String A_FG="fg"; //$NON-NLS-1$
	
	public static final String E_ORIENTATION="orientation"; //$NON-NLS-1$
	public static final String A_HORIZONTAL="horizontal"; //$NON-NLS-1$
	
	@Override
	public void writeControl( Control c, XMLWriter w, SceneWriter sw ) throws IOException 
	{
		if( process[ F_BOUNDS ] ) {
			w.startElement( E_BOUNDS );
			boolean ai = w.setAttributeIndented( false );
			w.addAttr( A_X, c.getLocation().x );
			w.addAttr( A_Y, c.getLocation().y );
			w.addAttr( A_W, c.getSize().x );
			w.addAttr( A_H, c.getSize().y );
			w.endElement( E_BOUNDS );
			w.setAttributeIndented( ai );
		}
		
		if( process[ F_ORIENTATION ] && c instanceof IOrientable ) {
			IOrientable o = (IOrientable)c;
			w.addElement( E_ORIENTATION, A_HORIZONTAL, o.isHorizontal() );
		}
		
		if( process[ F_BACKGROUND_COLOR ] || process[ F_FOREGROUND_COLOR ] ) {
			w.startElement( E_COLORS );
			boolean ai = w.setAttributeIndented( false );
			if( process[ F_BACKGROUND_COLOR ] ) w.addAttr( A_BG, c.getBackground() );
			if( process[ F_FOREGROUND_COLOR ] ) w.addAttr( A_FG, c.getForeground() );
			w.endElement( E_COLORS );
			w.setAttributeIndented( ai );
		}
	}
	
	@Override
	public void readControl( Control c, IXMLElement element, XMLReader r, SceneReader sr ) throws ReaderError 
	{
		if( process[ F_ORIENTATION ] && c instanceof IOrientable ) {
			IOrientable o = (IOrientable)c;
			
			IXMLElement e = r.getElement( element, E_ORIENTATION, true );
			boolean horiz = r.getAttrBoolean( e, A_HORIZONTAL );
			o.setHorizontal( horiz );
		}
		
		if( process[ F_BOUNDS ] ) {
			IXMLElement e = r.getElement( element, E_BOUNDS, true );
			int x = r.getAttrInt( e, A_X );
			int y = r.getAttrInt( e, A_Y );
			int w = r.getAttrInt( e, A_W );
			int h = r.getAttrInt( e, A_H );

			c.setBounds( x, y, w, h );
		}
		
		
		if( process[ F_BACKGROUND_COLOR ] || process[ F_FOREGROUND_COLOR ] ) {
			IXMLElement e_colors = r.getElement( element, E_COLORS, false );
			if( e_colors!=null ) {
				RGB rgb = r.getAttr( e_colors, A_BG, (RGB)null );
				if( rgb!=null ) {
					c.setBackground( new Color( c.getScene().getDisplay(), rgb ) );
				}
				rgb = r.getAttr( e_colors, A_FG, (RGB)null );
				if( rgb!=null ) {
					c.setForeground( new Color( c.getScene().getDisplay(), rgb ) );
				}
			}
		}
	}
}
